import * as React from 'react'
import { useRef, useState } from 'react'
import { Editor, Repl, Viewer } from 'v1-repl'
import { FullScreen, useFullScreenHandle } from 'react-full-screen'
import { Download, Expand, Laptop, Monitor, Smartphone } from 'lucide-react'
import type { ISearchInput } from '../../shared/types.js'
import { cn } from './lib/utils'
import { useGenCode } from './hooks/useGenCode.js'
import importMap from './repl/importMap'
import TooltipButton from './components/TooltipButton.js'
import { DownloadDialog } from './components/DownloadDialog.js'

interface ICoreReplProps {
  hidden: boolean
  searchInput: ISearchInput
  onCodeChange: (code: string) => void
}

const WidthMap = {
  phone: '375px',
  laptop: '800px',
  pc: '100%',
} as const
export function CoreRepl(props: ICoreReplProps) {
  const [codeChunk] = useGenCode(props.searchInput)
  const editorRef: Parameters<typeof Editor>['0']['ref'] = useRef(null)
  const handle = useFullScreenHandle()
  const [device, setDevice] = useState<keyof typeof WidthMap>('pc')
  React.useEffect(() => {
    const monaco = editorRef.current?.getMonaco()
    if (!monaco)
      return

    const disposable = monaco.onDidChangeModelContent(() => {
      const model = monaco.getModel()
      if (!model)
        return
      props.onCodeChange(model.getValue())
    })

    return () => disposable.dispose()
  }, [codeChunk])
  return (
    <Repl
      name="inula-playground"
      className={`h-full w-full${props.hidden ? ' hidden' : ''}`}
      split={{ split: 'horizontal', defaultSize: 600, pane1Style: { overflow: 'hidden' } }}
      code={codeChunk}
      importMap={JSON.stringify(importMap)}
      enableTabs={false}
      enableStorage={false}
    >
      <div className="flex h-full w-full flex-col bg-[#f3f3f3]" contentEditable="false">
        <div className="flex pt-2 pb-1 px-1 bg-white rounded-md border border-gs-gray-alpha-400 self-start">
          <TooltipButton tooltip={<p>pc</p>}>
            <button
              onClick={() => setDevice('pc')}
              className={cn('inline-flex items-center whitespace-nowrap shrink-0 justify-center text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 hover:bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] hover:text-[#171717] rounded-sm', { 'bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] text-[#171717]': device === 'pc' })}
            >
              <Monitor className="h-5 w-5" />
            </button>
          </TooltipButton>
          <TooltipButton tooltip={<p>laptop</p>}>
            <button
              onClick={() => setDevice('laptop')}
              className={cn('inline-flex items-center whitespace-nowrap shrink-0 justify-center text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 hover:bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] hover:text-[#171717] rounded-sm', { 'bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] text-[#171717]': device === 'laptop' })}
            >
              <Laptop className="h-5 w-5" />
            </button>
          </TooltipButton>
          <TooltipButton tooltip={<p>phone</p>}>
            <button
              onClick={() => setDevice('phone')}
              className={cn('inline-flex items-center whitespace-nowrap shrink-0 justify-center text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 hover:bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] hover:text-[#171717] rounded-sm', { 'bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] text-[#171717]': device === 'phone' })}
            >
              <Smartphone className="h-5 w-5" />
            </button>
          </TooltipButton>
          <div className="w-[2px] h-full bg-slate-400 mx-1"></div>
          <TooltipButton tooltip={<p>Fullscreen</p>}>
            <button className="inline-flex items-center whitespace-nowrap shrink-0 justify-center text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 hover:bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] hover:text-[#171717] rounded-sm">
              <Expand onClick={handle.enter} className="h-5 w-5" />
            </button>
          </TooltipButton>
          <TooltipButton tooltip={<p>Download</p>}>
            <DownloadDialog>
              <button className="inline-flex items-center whitespace-nowrap shrink-0 justify-center text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 hover:bg-gray-100 px-3 gap-[6px] py-1 h-6 text-[#666666] hover:text-[#171717] rounded-sm">
                <Download className="h-5 w-5" />
              </button>
            </DownloadDialog>
          </TooltipButton>
        </div>
        <FullScreen handle={handle} className="flex-1 select-none flex justify-center border-gs-gray-alpha-400">
          <Viewer className="bg-white my-2 rounded-lg border border-black/5 duration-200 transition-all" style={{ width: WidthMap[device], height: 'calc(100% - 1rem)' }} />
        </FullScreen>
      </div>
      <Editor ref={editorRef} className="rounded-md p-4 border-gs-gray-alpha-400" theme="dark" />

    </Repl>
  )
}
interface IMiniPreviewReplProps {
  code: string
}

export function MiniPreviewRepl(props: IMiniPreviewReplProps) {
  return (
    <Repl
      name="mini-preview-repl"
      className="h-[200%] w-[200%] scale-50 left-[-50%] top-[-50%] pointer-events-none"
      code={props.code}
      importMap={JSON.stringify(importMap)}
      enableTabs={false}
      enableStorage={false}
    >
      <Editor className="hidden" />
      <Viewer />
    </Repl>
  )
}
